package aop.test.advisor;

import aop.test.advice.SimpleMethodInvocation;
import cn.stimd.spring.aop.Advisor;
import cn.stimd.spring.aop.framework.adapter.AdvisorAdapterRegistry;
import cn.stimd.spring.aop.framework.adapter.DefaultAdvisorAdapterRegistry;
import org.aopalliance.intercept.MethodInterceptor;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by Stimd
 * 项目地址：https://gitee.com/stimd/spring-wheel
 * 公众号：Java编程探微
 */
public class AdvisorAdapterSupport {
    private Object target;
    private AdvisorAdapterRegistry registry = new DefaultAdvisorAdapterRegistry();
    private List<Advisor> advisors = new LinkedList<>();

    public void addAdvice(Object advice){
        Advisor advisor = this.registry.wrap(advice);
        this.advisors.add(advisor);
    }

    public void setTarget(Object target){
        this.target = target;
    }


    public void invoke(String methodName) throws Throwable {
        Method targetMethod = null;
        for (Method method : this.target.getClass().getDeclaredMethods()) {
            if(method.getName().equals(methodName)){
                targetMethod = method;
                break;
            }
        }

        List<MethodInterceptor> interceptorList = new ArrayList<>(this.advisors.size());
        for (Advisor advisor : this.advisors) {
            MethodInterceptor[] interceptors = this.registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
        }

        if(targetMethod != null){
            SimpleMethodInvocation mi = new SimpleMethodInvocation(targetMethod, this.target, interceptorList);
            mi.proceed();
        }
    }
}
